﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Tomahawk.Runtime.Logic.UI;
using Tomahawk.Runtime.Resources;

namespace Tomahawk.Runtime.Canvas.Sprite
{
    /// <summary>
    /// An UITextSprite is a text rendered to the UI.
    /// As it will be usually rendered between image components, 
    /// it will use the inmediate mode for best perf.
    /// </summary>
    public class UITextSprite : Sprite
    {
        /// <summary>
        /// Holds the font asset
        /// </summary>
        string fontAsset = "";

        private SpriteFont font;

        private Vector2 measuredSize;

        private Vector2 renderPosition;

        /// <summary>
        /// Shadow Color
        /// </summary>
        public Color ShadowColor = Color.Black;

        /// <summary>
        /// Shadow position
        /// </summary>
        public Point ShadowDisplacement = Point.Zero;

        /// <summary>
        /// Shadow enabled
        /// </summary>
        public bool ShadowEnabled = false;

        /// <summary>
        /// Stores the text as the user entered (unlocalized)
        /// </summary>
        private string text;

        /// <summary>
        /// Public property for the Font.
        /// </summary>
        public SpriteFont Font
        {
            get { return font; }
        }

        /// <summary>
        /// Update the text value
        /// </summary>
        public void SetText(string text)
        {
            this.text = text;
            if (font != null) this.measuredSize = this.font.MeasureString(text);
        }

        /// <summary>
        /// Horintal Centering of the text
        /// </summary>
        public XStyleManager.TextHAlign HAlign { get; set; }

        /// <summary>
        /// Constructor
        /// </summary>
        public UITextSprite(string fontAsset, string text, string effectChannel, ResourceManager.ResourcePool pool)
        {
            this.resourcePool = pool;
            this.fontAsset = fontAsset;
            this.text = text;
            this.EffectChannel = effectChannel;
        }

        /// <summary>
        /// Load contents
        /// </summary>
        protected override bool OnLoad(GraphicsDevice graphics, ContentManager contentManager)
        {
            //load the font
            font = contentManager.Load<SpriteFont>(this.fontAsset);

            //
            font.DefaultCharacter = '*';

            //
            return true;
        }

        private float fontScale = 1.0f;
        public float FontScale { get { return fontScale; } set { fontScale = value; } }

        private Vector2 origin = new Vector2(0.0f, 0.0f);
        public Vector2 Origin { get { return origin; } set { origin = value; } }

        private Vector2 offset = new Vector2(0.0f, 0.0f);
        public Vector2 Offset { get { return offset; } set { offset = value; } }

        private float rotation = 0.0f;
        public float Rotation { get { return rotation; } set { rotation = value; } }

        private Vector2 _screenPosition = new Vector2();

        /// <summary>
        /// Draw the primitive, must be called with an already opened and configured SpriteBatch
        /// </summary>
        public override void Render(SpriteBatch spriteBatch)
        {
            if (this.text != null)
            {
                float screenScale;
                
                //render shadow
                if (this.ShadowEnabled)
                {
                    if (HAlign == XStyleManager.TextHAlign.Left)
                    {
                        //left alignment
                        this.renderPosition.X = this.DestinationRectangle.X + this.ShadowDisplacement.X;
                        this.renderPosition.Y = this.DestinationRectangle.Y + this.ShadowDisplacement.Y;
                    }
                    else if (HAlign == XStyleManager.TextHAlign.Centered)
                    {
                        //horizontally centered location
                        this.renderPosition.X = this.DestinationRectangle.X + this.ShadowDisplacement.X + (this.DestinationRectangle.Width / 2) - (this.measuredSize.X / 2);
                        this.renderPosition.Y = this.DestinationRectangle.Y + this.ShadowDisplacement.Y;
                    }
                    else
                    {
                        //right aligment
                        this.renderPosition.X = this.DestinationRectangle.X + this.ShadowDisplacement.X + this.DestinationRectangle.Width - this.measuredSize.X;
                        this.renderPosition.Y = this.DestinationRectangle.Y + this.ShadowDisplacement.Y;
                    }

                    //draw
                    Engine.Instance.CanvasManager.ApplyVirtualCanvas(ref this.renderPosition, ref _screenPosition);
                    Engine.Instance.CanvasManager.ApplyVirtualCanvas(fontScale, out screenScale);
                    spriteBatch.DrawString(this.font, this.text, _screenPosition, this.ShadowColor, rotation, origin + offset, screenScale, SpriteEffects.None, this.Depth + 0.01f);
                }

                if (HAlign == XStyleManager.TextHAlign.Left)
                {
                    //discard width and height from destinationRectangle
                    this.renderPosition.X = this.DestinationRectangle.X;
                    this.renderPosition.Y = this.DestinationRectangle.Y;
                }
                else if (HAlign == XStyleManager.TextHAlign.Centered)
                {
                    //hotizontally centered location
                    this.renderPosition.X = this.DestinationRectangle.X + (this.DestinationRectangle.Width / 2) - (this.measuredSize.X / 2);
                    this.renderPosition.Y = this.DestinationRectangle.Y;
                }
                else 
                {
                    //right aligment
                    this.renderPosition.X = this.DestinationRectangle.X + this.DestinationRectangle.Width - this.measuredSize.X;
                    this.renderPosition.Y = this.DestinationRectangle.Y;
                }

                //render color
                Engine.Instance.CanvasManager.ApplyVirtualCanvas(ref this.renderPosition, ref _screenPosition);
                Engine.Instance.CanvasManager.ApplyVirtualCanvas(fontScale, out screenScale);
                spriteBatch.DrawString(this.font, this.text, _screenPosition, this.Color, rotation, origin + offset, screenScale, SpriteEffects.None, this.Depth);
            }
        }



    }

}
